home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / OldSrc / CH8 / SRC / FLAKEAN1.FRM (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1996-05-02  |  7.6 KB  |  268 lines

  1. VERSION 4.00
  2. Begin VB.Form FlakeForm 
  3.    Caption         =   "Snowflake"
  4.    ClientHeight    =   4365
  5.    ClientLeft      =   2280
  6.    ClientTop       =   1185
  7.    ClientWidth     =   5070
  8.    Height          =   5055
  9.    Left            =   2220
  10.    LinkTopic       =   "Form1"
  11.    ScaleHeight     =   291
  12.    ScaleMode       =   3  'Pixel
  13.    ScaleWidth      =   338
  14.    Top             =   555
  15.    Width           =   5190
  16.    Begin VB.TextBox ThetaText 
  17.       Height          =   285
  18.       Left            =   600
  19.       MaxLength       =   3
  20.       TabIndex        =   1
  21.       Text            =   "60"
  22.       Top             =   360
  23.       Width           =   375
  24.    End
  25.    Begin VB.TextBox LevelText 
  26.       Height          =   285
  27.       Left            =   600
  28.       MaxLength       =   3
  29.       TabIndex        =   0
  30.       Text            =   "4"
  31.       Top             =   0
  32.       Width           =   375
  33.    End
  34.    Begin VB.PictureBox Canvas 
  35.       AutoRedraw      =   -1  'True
  36.       Height          =   4335
  37.       Left            =   1080
  38.       ScaleHeight     =   285
  39.       ScaleMode       =   3  'Pixel
  40.       ScaleWidth      =   261
  41.       TabIndex        =   4
  42.       Top             =   0
  43.       Width           =   3975
  44.    End
  45.    Begin VB.CommandButton CmdGo 
  46.       Caption         =   "Go"
  47.       Default         =   -1  'True
  48.       Height          =   495
  49.       Left            =   120
  50.       TabIndex        =   2
  51.       Top             =   840
  52.       Width           =   735
  53.    End
  54.    Begin VB.Label Label1 
  55.       Caption         =   "Theta"
  56.       Height          =   255
  57.       Index           =   1
  58.       Left            =   0
  59.       TabIndex        =   5
  60.       Top             =   360
  61.       Width           =   495
  62.    End
  63.    Begin VB.Label Label1 
  64.       Caption         =   "Level"
  65.       Height          =   255
  66.       Index           =   0
  67.       Left            =   0
  68.       TabIndex        =   3
  69.       Top             =   0
  70.       Width           =   495
  71.    End
  72.    Begin VB.Menu mnuFile 
  73.       Caption         =   "&File"
  74.       Begin VB.Menu mnuFileExit 
  75.          Caption         =   "E&xit"
  76.       End
  77.    End
  78. Attribute VB_Name = "FlakeForm"
  79. Attribute VB_Creatable = False
  80. Attribute VB_Exposed = False
  81. Option Explicit
  82. Const PI = 3.14159
  83. Dim TheLevel As Integer
  84. Dim StartLength As Integer
  85. ' Coordinates of the points in the initiator.
  86. Const NumIni = 3
  87. Dim IniX(0 To NumIni) As Single
  88. Dim IniY(0 To NumIni) As Single
  89. ' Angles and distances for the generator.
  90. Const NumGen = 4
  91. Dim DistFactor As Single
  92. Dim GenDTheta(1 To NumGen) As Single
  93. Sub GetParameters()
  94. Dim theta As Single
  95.     If Not IsNumeric(LevelText.Text) Then _
  96.         LevelText.Text = "5"
  97.     TheLevel = CInt(LevelText.Text)
  98.     ' Initialize the generator.
  99.     If Not IsNumeric(ThetaText.Text) Then _
  100.         ThetaText.Text = "60"
  101.     theta = CInt(ThetaText.Text) / 180 * PI
  102.     DistFactor = 1 / (2 * (1 + Cos(theta)))
  103.     GenDTheta(1) = 0
  104.     GenDTheta(2) = theta
  105.     GenDTheta(3) = -2 * theta
  106.     GenDTheta(4) = theta
  107. End Sub
  108. ' ************************************************
  109. ' Recursively draw a snowflake edge starting at
  110. ' (x1, y1) in direction theta and distance dist.
  111. ' Leave the coordinates of the endpoint in
  112. ' (x1, y1).
  113. ' ************************************************
  114. Sub DrawFlakeEdge(level As Integer, x1 As Single, y1 As Single, ByVal theta As Single, ByVal dist As Single, offset As Single)
  115. Dim status As Integer
  116. Dim i As Integer
  117. Dim x2 As Single
  118. Dim y2 As Single
  119. Dim new_theta As Single
  120. Dim dtheta As Single
  121. Dim hyp As Single
  122. Dim adj As Single
  123.     If level <= 1 Then
  124.         ' Draw the final level.
  125.         dist = dist * DistFactor
  126.         adj = dist * Cos(GenDTheta(2))
  127.         hyp = Sqr(adj * adj + offset * offset)
  128.         x2 = x1 + dist * Cos(theta)
  129.         y2 = y1 + dist * Sin(theta)
  130.         Canvas.Line (x1, y1)-(x2, y2)
  131.         x1 = x2
  132.         y1 = y2
  133.         
  134.         dtheta = Arctan2(adj, offset)
  135.         new_theta = theta + dtheta
  136.         x2 = x1 + hyp * Cos(new_theta)
  137.         y2 = y1 + hyp * Sin(new_theta)
  138.         Canvas.Line (x1, y1)-(x2, y2)
  139.         x1 = x2
  140.         y1 = y2
  141.         
  142.         new_theta = theta - dtheta
  143.         x2 = x1 + hyp * Cos(new_theta)
  144.         y2 = y1 + hyp * Sin(new_theta)
  145.         Canvas.Line (x1, y1)-(x2, y2)
  146.         x1 = x2
  147.         y1 = y2
  148.         
  149.         x2 = x1 + dist * Cos(theta)
  150.         y2 = y1 + dist * Sin(theta)
  151.         Canvas.Line (x1, y1)-(x2, y2)
  152.         x1 = x2
  153.         y1 = y2
  154.         
  155.         Exit Sub
  156.     End If
  157.     ' Recursively draw the edge.
  158.     dist = dist * DistFactor
  159.     For i = 1 To NumGen
  160.         theta = theta + GenDTheta(i)
  161.         DrawFlakeEdge level - 1, x1, y1, theta, dist, offset
  162.     Next i
  163. End Sub
  164. ' ************************************************
  165. ' Draw the complete snowflake.
  166. ' ************************************************
  167. Private Sub DrawFlake(level As Integer, offset As Single)
  168. Dim i As Integer
  169. Dim x1 As Single
  170. Dim y1 As Single
  171. Dim x2 As Single
  172. Dim y2 As Single
  173. Dim dx As Single
  174. Dim dy As Single
  175. Dim theta As Single
  176.     Canvas.Cls
  177.     ' Draw the snowflake.
  178.     For i = 1 To NumIni
  179.         x1 = IniX(i - 1)
  180.         y1 = IniY(i - 1)
  181.         x2 = IniX(i)
  182.         y2 = IniY(i)
  183.         dx = x2 - x1
  184.         dy = y2 - y1
  185.         theta = Arctan2(dx, dy)
  186.         DrawFlakeEdge level, x1, y1, _
  187.             theta, StartLength, offset
  188.     Next i
  189. End Sub
  190. ' ************************************************
  191. ' Play the movie.
  192. ' ************************************************
  193. Private Sub CmdGo_Click()
  194.     MakeMovie False
  195. End Sub
  196. Private Sub Form_Resize()
  197. Dim unit As Single
  198. Dim vunit As Single
  199. Dim hunit As Single
  200. Dim xmid As Single
  201. Dim ymid As Single
  202.     Canvas.Move Canvas.Left, 0, _
  203.         ScaleWidth - Canvas.Left, ScaleHeight - 1
  204.     ' See how big we can make the curve.
  205.     vunit = 0.9 * Canvas.ScaleHeight / (Sqr(3) * 4 / 3)
  206.     hunit = 0.9 * Canvas.ScaleWidth / 2
  207.     If vunit < hunit Then
  208.         unit = vunit
  209.     Else
  210.         unit = hunit
  211.     End If
  212.     StartLength = 2 * unit
  213.     ' Initialize the initiator's coordinates.
  214.     xmid = Canvas.ScaleWidth / 2
  215.     ymid = Canvas.ScaleHeight / 2
  216.     IniX(1) = xmid + unit
  217.     IniY(1) = ymid - unit * Sqr(3) / 3
  218.     IniX(2) = xmid - unit
  219.     IniY(2) = IniY(1)
  220.     IniX(3) = xmid
  221.     IniY(3) = ymid + unit * Sqr(3) * 2 / 3
  222.     IniX(0) = IniX(3)
  223.     IniY(0) = IniY(3)
  224. End Sub
  225. Private Sub Form_Unload(Cancel As Integer)
  226.     End
  227. End Sub
  228. Private Sub mnuFileExit_Click()
  229.     Unload Me
  230. End Sub
  231. ' ************************************************
  232. ' Make a series of images.
  233. ' ************************************************
  234. Private Sub MakeMovie(to_file As Boolean)
  235. Const FRAMES_PER_LEVEL = 20
  236. Const FPS = 20
  237. Dim frame As Integer
  238. Dim i As Integer
  239. Dim offset As Single
  240. Dim doffset As Single
  241. Dim level As Integer
  242. Dim max_level As Integer
  243. Dim next_time As Long
  244. Dim mspf As Long
  245.     MousePointer = vbHourglass
  246.     GetParameters
  247.     max_level = TheLevel
  248.     ' Start cranking out frames.
  249.     frame = 0
  250.     mspf = 1000 \ FPS   ' Milliseconds per frame.
  251.     next_time = GetTickCount()
  252.     For level = 1 To max_level
  253.         doffset = StartLength * DistFactor ^ level * _
  254.             Sin(GenDTheta(2)) / FRAMES_PER_LEVEL
  255.         offset = doffset
  256.         
  257.         For i = 1 To FRAMES_PER_LEVEL
  258.             WaitTill next_time
  259.             DrawFlake level, offset
  260.             offset = offset + doffset
  261.             DoEvents
  262.             next_time = next_time + mspf
  263.         Next i
  264.         frame = frame + 1
  265.     Next level
  266.     MousePointer = vbDefault
  267. End Sub
  268.